﻿using Amib.Threading;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;

namespace IOPerformanceVerifier
{
    public class ThrottlerThread
    {
        private Logger _logger;
        private string _diskTestName;
        private string _internalDiskTestName;
        private IOController _ioController;
        private bool _initiated;

        public ThrottlerThread(string diskTestName, string internalDiskTestName)
        {
            _diskTestName = diskTestName;
            _internalDiskTestName = internalDiskTestName;
            _logger = Logger.Instance();
            _logger.log(LogLevel.Debug, _internalDiskTestName + ": Thread Created");
        }

        public void ThreadPoolCallback(Object inputThreadConfiguration)
        {
            ThreadConfigutation threadConfiguration = inputThreadConfiguration as ThreadConfigutation;
            _logger.log(LogLevel.Debug, threadConfiguration.InternalDiskTestName + ": Test runing");

            // Cancelled before work starts
            if (SmartThreadPool.IsWorkItemCanceled)
            {
                return;
            }

            if (_initiated)
            {
                // Cancelled when running or in queue
                while (!SmartThreadPool.IsWorkItemCanceled)
                {
                    doWork(threadConfiguration);
                }
                _logger.log(LogLevel.Debug, _internalDiskTestName + ": Cancellation Received");
                shutDownThread();
            }
            else
            {
                _logger.log(LogLevel.Debug, _internalDiskTestName + ": Not initiated");
            }
        }

        public bool inititateWork(ThreadConfigutation threadConfiguration)
        {
            _logger.log(LogLevel.Debug, _internalDiskTestName + ": File creation starting: " + threadConfiguration.AbsoluteFilePath);
            // Create file with random data
            if (IOController.createFile(threadConfiguration.AbsoluteFilePath, threadConfiguration.InternalFileSize))
            {
                _logger.log(LogLevel.Debug, _internalDiskTestName + ": File creation finished");
                _ioController = new IOController(threadConfiguration);
                _initiated = true;
                return true;
            }
            else
            {
                _logger.log(LogLevel.Error, _internalDiskTestName + ": File creation failed");
                return false;
            }
        }

        private void doWork(ThreadConfigutation threadConfiguration)
        {
            // Run Step
            _ioController.runStep();

            // Give control to other threads
            Thread.Yield();
        }

        private void shutDownThread()
        {
            _ioController.cleanUp();
            _logger.log(LogLevel.Debug, _internalDiskTestName + ": Thread shutting down");
        }

        public string DiskTestName
        {
            get
            {
                return _diskTestName;
            }
        }

        public string InternalDiskTestName
        {
            get
            {
                return _internalDiskTestName;
            }
        }
    }
}
